Submitted By: Ken Moffat <ken at linuxfromscratch dot org>
Date: 2019-08-14
Initial Package Version: 9.27
Upstream Status: Applied
Origin: Cherry-picked by debian security.
Description: Fixes CVE-2019-10216

The .buildfont1 procedure in Ghostscript does not properly restrict
privileged calls, which could result in bypass of file system
restrictions of the dSAFER sandbox.

Debian patches 020190410~06c9207.patch and 020190802~5b85ddd.patch.

Description: Fix regression resolving bounding box of font glyphs
 Re-introduce over/underflow workaround
 .
 Commit 355434f4b1bbe8c4f98cafad5a6868aa2f0eaae1 reverted a workaround
 that compensated for over/underflow in Freetype's TTF hinting
 (related to freedom and projection vector calculations).
 That problem no longer exists in recent Freetype releases,
 and the workaround actually caused other issues to occur with hinting.
 .
 What wasn't obvious was
 that the workaround also protected over/underflow issues
 relating to the unitsPerEm value.
 .
 So this re-instates the workaround,
 but bases the decision on how the final scale is distributing
 between the Freetype "size" and the Freetype matrix
 on the unitsPerEm value
 (this is relevant for all font types
 as for non-TTF font types
 Freetype derives the unitsPerEm from the FontMatrix for PS type fonts).
Origin: upstream, http://git.ghostscript.com/?p=ghostpdl.git;h=06c9207
Author: Chris Liddell <chris.liddell@artifex.com>
Forwarded: yes
Bug: http://bugs.ghostscript.com/show_bug.cgi?id=700952
Bug: http://bugs.ghostscript.com/show_bug.cgi?id=700875
Bug-Debian: https://bugs.debian.org/927429
Last-Update: 2019-04-20
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/base/fapi_ft.c
+++ b/base/fapi_ft.c
@@ -974,13 +974,19 @@
  */
 static void
 transform_decompose(FT_Matrix * a_transform, FT_UInt * xresp, FT_UInt * yresp,
-                    FT_Fixed * a_x_scale, FT_Fixed * a_y_scale)
+                    FT_Fixed * a_x_scale, FT_Fixed * a_y_scale, int units_per_EM)
 {
     double scalex, scaley, fact = 1.0;
     double factx = 1.0, facty = 1.0;
     FT_Matrix ftscale_mat;
     FT_UInt xres;
     FT_UInt yres;
+    /* We have to account for units_per_EM as we fiddle with the scaling
+     * in order to avoid underflow (mostly in the TTF hinting code), but
+     * we also want to clamp to a lower value (512, admittedly arrived at
+     * via experimentation) in order to preserve the fidelity of the outlines.
+     */
+    double upe = units_per_EM > 512 ? (float)units_per_EM : 512.0;
 
     scalex = hypot((double)a_transform->xx, (double)a_transform->xy);
     scaley = hypot((double)a_transform->yx, (double)a_transform->yy);
@@ -1067,10 +1073,25 @@
         scalex *= fact;
     }
 
-    ftscale_mat.xx = (FT_Fixed) (65536.0 / scalex);
-    ftscale_mat.xy = (FT_Fixed) 0;
-    ftscale_mat.yx = (FT_Fixed) 0;
-    ftscale_mat.yy = (FT_Fixed) (65536.0 / scaley);
+    /* see above */
+    fact = 1.0;
+    while (scaley * yres > (double)upe * 72.0 && (xres > 0 && yres > 0)
+           && (scalex > 0.0 && scaley > 0.0)) {
+        if (scaley < yres) {
+            xres >>= 1;
+            yres >>= 1;
+            fact *= 2.0;
+        }
+        else {
+            scalex /= 1.25;
+            scaley /= 1.25;
+        }
+    }
+
+    ftscale_mat.xx = (FT_Fixed) ((65536.0 / scalex) * fact);
+    ftscale_mat.xy = 0;
+    ftscale_mat.yx = 0;
+    ftscale_mat.yy = (FT_Fixed) ((65536.0 / scaley) * fact);
 
     FT_Matrix_Multiply(a_transform, &ftscale_mat);
     memcpy(a_transform, &ftscale_mat, sizeof(FT_Matrix));
@@ -1315,7 +1336,7 @@
          * transform.
          */
         transform_decompose(&face->ft_transform, &face->horz_res,
-                            &face->vert_res, &face->width, &face->height);
+                            &face->vert_res, &face->width, &face->height, face->ft_face->units_per_EM);
 
         ft_error = FT_Set_Char_Size(face->ft_face, face->width, face->height,
                                     face->horz_res, face->vert_res);
From: Chris Liddell <chris.liddell@artifex.com>
Date: Fri, 2 Aug 2019 15:18:26 +0100
Subject: Bug 701394: protect use of .forceput with executeonly
Origin: http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=5b85ddd19a8420a1bd2d5529325be35d78e94234
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-10216
Bug: https://bugs.ghostscript.com/show_bug.cgi?id=701394

---
 Resource/Init/gs_type1.ps | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/Resource/Init/gs_type1.ps b/Resource/Init/gs_type1.ps
index 6c7735bc0cc3..a039ccee3590 100644
--- a/Resource/Init/gs_type1.ps
+++ b/Resource/Init/gs_type1.ps
@@ -118,25 +118,25 @@
                          ( to be the same as glyph: ) print 1 index //== exec } if
                    3 index exch 3 index .forceput
                                                                  % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname
-                 }
+                 }executeonly
                  {pop} ifelse
-               } forall
+               } executeonly forall
                pop pop
-             }
+             } executeonly
              {
                pop pop pop
              } ifelse
-           }
+           } executeonly
            {
                                                                % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname
              pop pop
            } ifelse
-         } forall
+         } executeonly forall
          3 1 roll pop pop
-     } if
+     } executeonly if
      pop
      dup /.AGLprocessed~GS //true .forceput
-   } if
+   } executeonly if
 
    %% We need to excute the C .buildfont1 in a stopped context so that, if there
    %% are errors we can put the stack back sanely and exit. Otherwise callers won't
-- 
2.20.1

